package com.eva.androidlibrary.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.SurfaceHolder;

import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;

/**
 * Created by guxun on 15/9/16.
 */
public class ScanCamera implements Camera.AutoFocusCallback {
    public static final int mWidth = 1600;
    public static final int mHeight = 1200;
    private Camera mCamera;
    private Handler mHandler;
    private int takeType = 100;
    private AutoFocusSuccessListener mAutoFocusListner;
    private Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() {
        public void onAutoFocus(boolean success, Camera camera) {
            if(mAutoFocusListner!=null)
                mAutoFocusListner.onAutoFocusSuccess();
        }
    };
    private Camera.ShutterCallback shutterCallback = new Camera.ShutterCallback() {
        public void onShutter() {
        }
    };
    private Camera.PictureCallback rawCallback = new Camera.PictureCallback() {
        public void onPictureTaken(byte[] _data, Camera _camera) {
        }
    };
    private Camera.PictureCallback jpegCallback = new Camera.PictureCallback() {
        public void onPictureTaken(byte[] _data, Camera _camera) {
            try {
                String e = newImageName();
                Bitmap bm = BitmapFactory.decodeByteArray(_data, 0, _data.length);
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                bm.compress(Bitmap.CompressFormat.JPEG, 50, bos);
                Message msg = new Message();
                msg.what = ScanCamera.this.takeType;
                msg.obj = e;
                Bundle bundle = new Bundle();
                bundle.putByteArray("img_data", bos.toByteArray());
                msg.setData(bundle);
                ScanCamera.this.mHandler.sendMessage(msg);
                bos.flush();
                bos.close();
                bm.recycle();
            } catch (NullPointerException var8) {
                ScanCamera.this.mHandler.sendEmptyMessage(0);
            } catch (FileNotFoundException var9) {
                ScanCamera.this.mHandler.sendEmptyMessage(0);
            } catch (IOException var10) {
                ScanCamera.this.mHandler.sendEmptyMessage(0);
            }

        }
    };

    public static String newImageName() {
        String uuidStr = UUID.randomUUID().toString();
        return uuidStr.replaceAll("-", "") + ".jpg";
    }

    public ScanCamera(Context context, Handler handler, AutoFocusSuccessListener listner) {
        this.mHandler = handler;
        this.mAutoFocusListner = listner;
    }

    public void openCamera(SurfaceHolder holder) throws RuntimeException, IOException {
        if(this.mCamera == null) {
            this.mCamera = Camera.open();
            this.mCamera.setPreviewDisplay(holder);
            this.setPictureSize();
        }

    }

    public void startDisplay() {
        if (this.mCamera != null) {
            this.mCamera.startPreview();
        }
    }

    public void setAutoFocusModes() {
        Camera.Parameters parameters = mCamera.getParameters();
        List<String> focusModes = parameters.getSupportedFocusModes();
        if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
        }
        mCamera.setParameters(parameters);
    }

    public void closeCamera() {
        if(this.mCamera != null) {
            this.mCamera.stopPreview();
            this.mCamera.release();
            this.mCamera = null;
        }
    }

    public void autoFocusAndTakePic(int type) {
        if(this.mCamera != null) {
            this.takeType = type;
            this.mCamera.autoFocus(this);
        }
    }

    public void autoFocus() {
        if(this.mCamera != null) {
            this.mCamera.autoFocus(this.autoFocusCallback);
        }
    }

    public void takePicture() {
        if(this.mCamera != null) {
            try {
                Camera.Parameters parameters = this.mCamera.getParameters();
                parameters.setJpegQuality(100);
                this.mCamera.setParameters(parameters);
                this.mCamera.takePicture(this.shutterCallback, this.rawCallback, this.jpegCallback);
            } catch (RuntimeException var2) {
                ;
            }
        }
    }

    public void setPreviewSize(int width, int height) {
        if(this.mCamera != null) {
            Camera.Parameters parameters = this.mCamera.getParameters();
            List previewSize = parameters.getSupportedPreviewSizes();
            Collections.sort(previewSize, new ScanCamera.SizeComparator());
            if(previewSize != null) {
                int size = previewSize.size();
                int picIndex = 0;

                for(int i = 0; i < size; ++i) {
                    if(((Camera.Size)previewSize.get(i)).width == width) {
                        picIndex = i;
                        break;
                    }

                    if(((Camera.Size)previewSize.get(i)).width < width) {
                        picIndex = i - 1;
                        if(picIndex < 0) {
                            picIndex = 0;
                        }

                        int diffW1 = ((Camera.Size)previewSize.get(picIndex)).width - width;
                        int diffW2 = width - ((Camera.Size)previewSize.get(i)).width;
                        if(diffW1 > diffW2) {
                            picIndex = i;
                        }
                        break;
                    }
                }

                if(Build.MODEL.startsWith("MI-ONE")) {
                    if(Build.VERSION.INCREMENTAL.equals("2.10.12")) {
                        parameters.setPreviewSize(640, 480);
                    } else {
                        parameters.setPreviewSize(1280, 720);
                    }
                } else {
                    parameters.setPreviewSize(((Camera.Size)previewSize.get(picIndex)).width, ((Camera.Size)previewSize.get(picIndex)).height);
                }
            }

            this.mCamera.setParameters(parameters);
        }

    }

    private void setPictureSize() {
        Camera.Parameters parameters = this.mCamera.getParameters();
        parameters.setPictureFormat(256);
        List pictureSize = parameters.getSupportedPictureSizes();
        Collections.sort(pictureSize, new ScanCamera.SizeComparator());
        if(pictureSize != null) {
            int size = pictureSize.size();
            int picIndex = 0;

            for(int i = 0; i < size; ++i) {
                if(((Camera.Size)pictureSize.get(i)).width == 1600) {
                    picIndex = i;
                    break;
                }

                if(((Camera.Size)pictureSize.get(i)).width < 1600) {
                    picIndex = i - 1;
                    if(picIndex < 0) {
                        picIndex = 0;
                    }

                    int diffW1 = ((Camera.Size)pictureSize.get(picIndex)).width - 1600;
                    int diffW2 = 1600 - ((Camera.Size)pictureSize.get(i)).width;
                    if(diffW1 > diffW2 && ((Camera.Size)pictureSize.get(i)).width > 1280) {
                        picIndex = i;
                    }
                    break;
                }
            }

            if(!Build.MODEL.startsWith("HTC 606w") && !Build.MODEL.startsWith("HTC 608t")) {
                parameters.setPictureSize(((Camera.Size)pictureSize.get(picIndex)).width, ((Camera.Size)pictureSize.get(picIndex)).height);
            } else {
                parameters.setPictureSize(1600, 1200);
            }
        }

        this.mCamera.setParameters(parameters);
    }

    public void setCameraFlashMode(String mode) {
        Camera.Parameters parameters = this.mCamera.getParameters();
        parameters.setFlashMode(mode);
        this.mCamera.setParameters(parameters);
    }

    public boolean isSupportFlash(String mode) {
        List modes = this.mCamera.getParameters().getSupportedFlashModes();
        return this.mCamera != null && modes != null && modes.contains(mode);
    }

    public boolean isSupportAutoFocus() {
        List list = this.getSupportedFocusModes();
        if(list == null) {
            return false;
        } else {
            Iterator var3 = list.iterator();

            while(var3.hasNext()) {
                String string = (String)var3.next();
                if("auto".equals(string)) {
                    return true;
                }
            }

            return false;
        }
    }

    public boolean isSupportFocus(String mode) {
        List list = this.getSupportedFocusModes();
        if(list == null) {
            return false;
        } else {
            Iterator var4 = list.iterator();

            while(var4.hasNext()) {
                String string = (String)var4.next();
                if(mode.equals(string)) {
                    return true;
                }
            }

            return false;
        }
    }

    private List<String> getSupportedFocusModes() {
        List list = null;
        if(this.mCamera != null) {
            Camera.Parameters parameters = this.mCamera.getParameters();
            list = parameters.getSupportedFocusModes();
            Iterator var4 = list.iterator();

            while(var4.hasNext()) {
                String string = (String)var4.next();
                Log.d("path", "------SupportedFocusModes----------->>" + string);
            }
        }

        return list;
    }

    public String getDefaultFlashMode() {
        return this.mCamera.getParameters().getSupportedFlashModes() != null?(String)this.mCamera.getParameters().getSupportedFlashModes().get(0):"off";
    }

    public void onAutoFocus(boolean success, Camera camera) {
        this.takePicture(success);
    }

    private void takePicture(boolean captureOnly) throws RuntimeException {
        if(this.mCamera != null) {
            try {
                Camera.Parameters parameters = this.mCamera.getParameters();
                parameters.setJpegQuality(100);
                this.mCamera.setParameters(parameters);
                this.mCamera.takePicture(this.shutterCallback, this.rawCallback, this.jpegCallback);
            } catch (RuntimeException var3) {
                ;
            }
        }

    }

    public class SizeComparator implements Comparator<Camera.Size> {
        public SizeComparator() {
        }

        public int compare(Camera.Size s1, Camera.Size s2) {
            return s2.width * s2.height - s1.width * s1.height;
        }
    }

    public interface AutoFocusSuccessListener {
        void onAutoFocusSuccess();
    }

}
